%% CDMA主函数 - 码分多址仿真
% 本程序模拟了码分多址接入技术，这是第三代移动通信(3G)使用的多址接入技术
% 在CDMA中，不同用户使用不同的扩频码，在同一时间同一频带内传输

clear all;
close all;
clc;

%% 参数设置
num_users = 8;           % 用户数量
spreading_factor = 32;   % 扩频因子
num_bits = 100;          % 每个用户的比特数
mod_type = 'BPSK';       % 调制类型
snr_dB = 10;             % 信噪比(dB)
code_type = 'Walsh';     % 扩频码类型: 'Walsh', 'Gold', 'Kasami'

% 功率控制设置 (近远效应)
power_control = true;    % 是否启用功率控制
if power_control
    % 用户功率为0dB-6dB
    user_powers_dB = 6*rand(1, num_users);  
else
    % 所有用户功率相同
    user_powers_dB = zeros(1, num_users);  
end
user_powers = 10.^(user_powers_dB/10);

fprintf('CDMA仿真开始，共%d个用户，扩频因子%d\n', num_users, spreading_factor);

%% 生成扩频序列
spreading_codes = generate_spreading_codes(num_users, spreading_factor, code_type);

% 显示扩频码相关性矩阵
code_correlation = calculate_code_correlation(spreading_codes);
fprintf('扩频码相关性矩阵计算完成\n');

%% 生成用户数据
user_data = cell(1, num_users);
user_symbols = cell(1, num_users);
spread_symbols = cell(1, num_users);

fprintf('生成用户数据...\n');
for user = 1:num_users
    % 生成随机二进制数据
    user_data{user} = randi([0, 1], 1, num_bits);
    
    % 调制符号
    user_symbols{user} = modulate_symbols(user_data{user}, mod_type);
    
    % 扩频
    spread_symbols{user} = spread_data(user_symbols{user}, spreading_codes(user, :));
    
    fprintf('用户 %d 数据已生成和扩频\n', user);
end

%% 复用并传输
% 所有用户信号的叠加
cdma_signal = zeros(1, num_bits * spreading_factor);

for user = 1:num_users
    % 应用功率控制
    cdma_signal = cdma_signal + sqrt(user_powers(user)) * spread_symbols{user};
end

% 添加噪声
noisy_signal = add_awgn_to_cdma(cdma_signal, snr_dB);

%% 接收解扩
received_bits = cell(1, num_users);
ber = zeros(1, num_users);

fprintf('接收和解扩...\n');
for user = 1:num_users
    % 解扩
    despread_symbols = despread_data(noisy_signal, spreading_codes(user, :), num_bits);
    
    % 解调
    received_bits{user} = demodulate_symbols(despread_symbols, mod_type);
    
    % 计算误码率
    bit_errors = sum(received_bits{user} ~= user_data{user});
    ber(user) = bit_errors / length(user_data{user});
    
    fprintf('用户 %d 的误码率: %.6f\n', user, ber(user));
end

% 平均误码率
avg_ber = mean(ber);
fprintf('平均误码率: %.6f\n', avg_ber);

%% 可视化
fprintf('绘制CDMA系统图形...\n');

% 绘制扩频码相关性
figure;
imagesc(code_correlation);
colorbar;
title('扩频码相关性矩阵');
xlabel('用户索引');
ylabel('用户索引');
colormap('jet');

% 示出用户信号叠加效果
figure;
subplot(3, 1, 1);
stem(1:20, user_data{1}(1:20), 'b');
title('用户1原始比特');
xlabel('比特索引');
ylabel('值');
ylim([-0.2, 1.2]);

subplot(3, 1, 2);
plot(1:20*spreading_factor, real(spread_symbols{1}(1:20*spreading_factor)), 'b');
title('扩频后的信号 (用户1)');
xlabel('芯片索引');
ylabel('值');

subplot(3, 1, 3);
plot(1:20*spreading_factor, real(noisy_signal(1:20*spreading_factor)), 'r');
title('接收到的CDMA混合信号 (所有用户+噪声)');
xlabel('芯片索引');
ylabel('值');

% 绘制用户功率和误码率关系
figure;
bar([user_powers_dB', ber']);
legend('功率 (dB)', '误码率');
title('用户功率与误码率关系');
xlabel('用户索引');
grid on;

fprintf('CDMA仿真完成!\n'); 